

#include "BSP.h"

#include "contract.h"
#include "IO.h"

typedef struct Uart{
	uint32_t entity;
	void(*cb)(uint16_t);
}Uart_T;

typedef struct UartHw{
	AFIO_T tx;
	AFIO_T rx;
	rcu_periph_enum rcu;
	IRQn_Type irqn;
}UartHw_T;

static void uart_rx_dummy(uint16_t rx){
	(void)rx;
}

static Uart_T uarts[] = {
	[0] = {	.entity = USART0,uart_rx_dummy},
	[1] = {	.entity = USART1,uart_rx_dummy},
	[2] = {	.entity = USART2,uart_rx_dummy},
};

static const UartHw_T uartHws[] = {
	[0] = {
		.tx = AFIO_INIT(GPIOA, GPIO_PIN_0, GPIO_AF_0),
		.rx = AFIO_INIT(GPIOA, GPIO_PIN_1, GPIO_AF_0),
		.rcu = RCU_USART0,
		.irqn = USART0_IRQn,
	},
	
	[1] = {
		.tx = AFIO_INIT(GPIOB, GPIO_PIN_15, GPIO_AF_7),
		.rx = AFIO_INIT(GPIOA, GPIO_PIN_8, GPIO_AF_3),
		.rcu = RCU_USART1,
		.irqn = USART1_IRQn,
	},
	
	[2] = {
		.tx = AFIO_INIT(GPIOA, GPIO_PIN_6, GPIO_AF_10),
		.rx = AFIO_INIT(GPIOA, GPIO_PIN_7, GPIO_AF_8),
		.rcu = RCU_USART2,
		.irqn = USART2_IRQn,
	},

};

static void BSP_Uart_IO_Init(const AFIO_T* afio){
	uint32_t gp = (uint32_t)afio->io.port;
	uint16_t pin = afio->io.pin;
	uint8_t af = afio->af;
	
	IO_Active(&afio->io);
    /* connect port to USARTx_Tx */
    gpio_af_set(gp, af, pin);
    /* configure USART Tx as alternate function push-pull */
    gpio_mode_set(gp, GPIO_MODE_AF, GPIO_PUPD_PULLUP,pin);
    gpio_output_options_set(gp, GPIO_OTYPE_PP, GPIO_OSPEED_25MHZ,pin);
}

static int BSP_Uart_CheckAFIO(const AFIO_T* io){
	return io && io->io.port != 0;
}

static void BSP_Uart_HwInit(const UartHw_T* hw){

    /* USART interrupt configuration */
    nvic_irq_enable(hw->irqn, 13, 0);

    /* enable USART clock */
    rcu_periph_clock_enable(hw->rcu);

	if(BSP_Uart_CheckAFIO(&hw->tx)){
		BSP_Uart_IO_Init(&hw->tx);
	}
	if(BSP_Uart_CheckAFIO(&hw->rx)){
		BSP_Uart_IO_Init(&hw->rx);
	}
}

static void BSP_Uart_Config(const Uart_T* uart, uint32_t baud){
	uint32_t com = uart->entity;
    /* USART configure */
    usart_deinit(com);
    usart_baudrate_set(com, baud);
    usart_word_length_set(com, USART_WL_8BIT);
    usart_stop_bit_set(com, USART_STB_1BIT);
    usart_parity_config(com, USART_PM_NONE);
    usart_hardware_flow_rts_config(com, USART_RTS_DISABLE);
    usart_hardware_flow_cts_config(com, USART_CTS_DISABLE);
    usart_receive_config(com, USART_RECEIVE_ENABLE);
    usart_transmit_config(com, USART_TRANSMIT_ENABLE);
    usart_enable(com);	

	/* enable  receive interrupt */
    usart_interrupt_enable(com, USART_INT_RBNE);
}

void BSP_Uart_Init(uint8_t id){
	REQUIRE(id < 5);
	BSP_Uart_HwInit(&uartHws[id]);
	BSP_Uart_Config(&uarts[id], 115200);
}


void BSP_Uart_Deinit(uint8_t id){
	REQUIRE(id < 5);
	usart_deinit(uarts[id].entity);
}

void BSP_Uart_TxRxConfig(uint8_t id, uint8_t txrx, uint8_t cfg){
	REQUIRE(id < 5);
	uint32_t com = uarts[id].entity;
	if(txrx & 0x01){
		if(cfg & 0x01){
			usart_transmit_config(com, USART_TRANSMIT_ENABLE);
		}
		else{
			usart_transmit_config(com, USART_TRANSMIT_DISABLE);
		}
	}
	if(txrx & 0x02){
		if(cfg & 0x02){
			usart_receive_config(com, USART_RECEIVE_ENABLE);
//				usart_interrupt_enable(com, USART_INT_RBNE);
//				usart_interrupt_flag_clear(com, USART_INT_RBNE);
		}
		else{
			usart_receive_config(com, USART_RECEIVE_DISABLE);
//				usart_interrupt_disable(com, USART_INT_RBNE);
//				usart_interrupt_flag_clear(com, USART_INT_RBNE);
		}
	}
}

void BSP_Uart_SetBaud(uint8_t id, uint32_t baud){
	REQUIRE(id < 5);
	usart_baudrate_set(uarts[id].entity, baud);
}


void BSP_Uart_SetRxCallback(uint8_t id, void(*cb)(uint16_t rx)){
	REQUIRE(id < 5);
	REQUIRE(cb);
	uarts[id].cb = cb;
}

void BSP_Uart_Send(uint8_t id, uint8_t tx){
	uint32_t i = 0;
	uint32_t com = uarts[id].entity;
	REQUIRE(id < 5);
	
    while(RESET == usart_flag_get(com, USART_FLAG_TBE)){
		if(++i > 100000){
			break;
		}
	}
    usart_data_transmit(com, tx);
    while(RESET == usart_flag_get(com, USART_FLAG_TBE)){
		if(++i > 100000){
			break;
		}
	}
}

void BSP_Uart_SendBuf(uint8_t id, const uint8_t buf[], uint32_t len){
	uint32_t i;

	for(i = 0; i < len; i++){
		BSP_Uart_Send(id, buf[i]);
	}
}
/*----------------------------------------------------------------------------------------------------------------------------------------*/

typedef struct {
	void* dma_buf;
	uint32_t dma_buf_size;
	uint32_t dma_countor;
	void (*dma_rx_cb)(uint8_t* data, uint32_t size);
	void(*dma_tx_cb)(uint8_t flag);
	uint8_t dma_tx_flag;
}uart_dma_config_t;

typedef struct {
	uint32_t dma_periph;
	uint32_t tx_data_address, rx_data_address;
	dma_channel_enum tx_channel, rx_channel;
	uart_dma_config_t* config;
	uint8_t subperi;
	uint8_t tx_irqn;
	uint8_t rx_irqn;
}uart_dma_t;

//	#define USART2_TDATA_ADDRESS      ((uint32_t)&USART_TDATA(USART2))
//	#define USART2_RDATA_ADDRESS      ((uint32_t)&USART_RDATA(USART2))

#define USART_TDATA_ADDRESS(usartx)    ((uint32_t)&USART_TDATA(usartx))
#define USART_RDATA_ADDRESS(usartx)    ((uint32_t)&USART_RDATA(usartx))

static uart_dma_config_t uart_dma_configs[3];

static const uart_dma_t uart_dmas[3] = {
	[0] = {.dma_periph = DMA1, 
		.tx_data_address = USART_TDATA_ADDRESS(USART0),
		.rx_data_address = USART_RDATA_ADDRESS(USART0),
		.tx_channel = DMA_CH7, .rx_channel = DMA_CH5, .config = &uart_dma_configs[0], 
		.subperi = DMA_SUBPERI4,
		.tx_irqn = DMA1_Channel7_IRQn, .rx_irqn = DMA1_Channel5_IRQn, },
		
	[1] = {.dma_periph = DMA0, 
		.tx_data_address = USART_TDATA_ADDRESS(USART1),
		.rx_data_address = USART_RDATA_ADDRESS(USART1),
		.tx_channel = DMA_CH6, .rx_channel = DMA_CH5, .config = &uart_dma_configs[1], 
		.subperi = DMA_SUBPERI4,
		.tx_irqn = DMA0_Channel6_IRQn, .rx_irqn = DMA0_Channel5_IRQn, },
		
	[2] = {.dma_periph = DMA0, 
		.tx_data_address = USART_TDATA_ADDRESS(USART2),
		.rx_data_address = USART_RDATA_ADDRESS(USART2),
		.tx_channel = DMA_CH3, .rx_channel = DMA_CH1, .config = &uart_dma_configs[2],
		.subperi = DMA_SUBPERI4,
		.tx_irqn = DMA0_Channel3_IRQn, .rx_irqn = DMA0_Channel1_IRQn, },
 
};


/*!
    \brief      configure the DMA1 channel 3 for transferring data
    \param[in]  srcbuf: a pointer point to a buffer which will be transferred
    \param[in]  bufsize: the size of buffer(not used in flow controller is peripheral)
    \param[out] none
    \retval     none
*/
static void uart_dma_transfer_config(const uart_dma_t* uart_dma, void *srcbuf, uint32_t bufsize)
{
	uint32_t dma_periph = uart_dma->dma_periph;
	dma_channel_enum dma_channel = uart_dma->tx_channel;
//	    dma_parameter_struct dma_init_struct;
    /* clear all the interrupt flags */
	dma_interrupt_flag_clear(dma_periph, dma_channel, DMA_INT_FLAG_FTF);
	dma_interrupt_flag_clear(dma_periph, dma_channel, DMA_INTF_SDEIF);
	dma_interrupt_flag_clear(dma_periph, dma_channel, DMA_INTF_TAEIF);
	dma_interrupt_flag_clear(dma_periph, dma_channel, DMA_INTF_HTFIF);
	dma_interrupt_flag_clear(dma_periph, dma_channel, DMA_INT_FLAG_FEE);
    dma_channel_disable(dma_periph, dma_channel);
    dma_deinit(dma_periph, dma_channel);
	
    dma_single_data_parameter_struct dma_init_struct;
    /* enable the DMA0 clock */
//	    rcu_periph_clock_enable(RCU_DMA0);
    /* configure the DMA0 channe3 */
    dma_deinit(dma_periph, dma_channel);
    dma_single_data_para_struct_init(&dma_init_struct);
    dma_init_struct.direction = DMA_MEMORY_TO_PERIPH;
    dma_init_struct.memory0_addr = (uint32_t)srcbuf;
    dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
    dma_init_struct.periph_memory_width = DMA_MEMORY_WIDTH_8BIT;
    dma_init_struct.number = bufsize;
    dma_init_struct.periph_addr = uart_dma->tx_data_address;
    dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
    dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
    dma_single_data_mode_init(dma_periph, dma_channel, &dma_init_struct);
    dma_channel_subperipheral_select(dma_periph, dma_channel, uart_dma->subperi);
    dma_circulation_disable(dma_periph, dma_channel);

    dma_channel_enable(dma_periph, dma_channel);
	
	uint32_t source = DMA_INT_FTF|DMA_INT_FEE;
 	dma_interrupt_enable(dma_periph, dma_channel, source);
    dma_channel_enable(dma_periph, dma_channel);
    nvic_irq_enable(uart_dma->tx_irqn, 13, 0);
}

#if 0
static void uart_dma_transfer_config(const uart_dma_t* uart_dma, void *srcbuf, uint32_t bufsize)
{
	uint32_t dma_periph = uart_dma->dma_periph;
	dma_channel_enum dma_channel = uart_dma->tx_channel;
    dma_parameter_struct dma_init_struct;
    /* clear all the interrupt flags */
    dma_flag_clear(dma_periph, dma_channel, DMA_FLAG_G);
    dma_flag_clear(dma_periph, dma_channel, DMA_FLAG_FTF);
    dma_flag_clear(dma_periph, dma_channel, DMA_FLAG_HTF);
    dma_flag_clear(dma_periph, dma_channel, DMA_FLAG_ERR);
    dma_channel_disable(dma_periph, dma_channel);
    dma_deinit(dma_periph, dma_channel);
    
    /* configure the DMA1 channel3 */
    dma_init_struct.direction = DMA_MEMORY_TO_PERIPHERAL;
    dma_init_struct.memory_addr = (uint32_t)srcbuf;
    dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
    dma_init_struct.number = bufsize;
    dma_init_struct.periph_addr = uart_dma->data_address;
    dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
    dma_init_struct.priority = DMA_PRIORITY_MEDIUM;
    dma_init(dma_periph, dma_channel, dma_init_struct);
    dma_memory_to_memory_disable(dma_periph, dma_channel);
    dma_circulation_disable(dma_periph, dma_channel);
	uint32_t source = DMA_INT_FTF|DMA_INT_ERR;
 	dma_interrupt_enable(dma_periph, dma_channel, source);
    dma_channel_enable(dma_periph, dma_channel);
    nvic_irq_enable(uart_dma->tx_irqn, 13, 1);
}
#endif 

/*!
    \brief      configure the DMA1 channel 3 for receiving data
    \param[in]  dstbuf: a pointer point to a buffer which will receive data
    \param[in]  bufsize: the size of buffer(not used in flow controller is peripheral)
    \param[out] none
    \retval     none
*/
static void uart_dma_receive_config(const uart_dma_t* uart_dma)
{
	uint32_t dma_periph = uart_dma->dma_periph;
	dma_channel_enum dma_channel = uart_dma->rx_channel;
    /* clear all the interrupt flags */
	dma_interrupt_flag_clear(dma_periph, dma_channel, DMA_INT_FLAG_FTF);
	dma_interrupt_flag_clear(dma_periph, dma_channel, DMA_INTF_SDEIF);
	dma_interrupt_flag_clear(dma_periph, dma_channel, DMA_INTF_TAEIF);
	dma_interrupt_flag_clear(dma_periph, dma_channel, DMA_INTF_HTFIF);
	dma_interrupt_flag_clear(dma_periph, dma_channel, DMA_INT_FLAG_FEE);
    dma_channel_disable(dma_periph, dma_channel);
    dma_deinit(dma_periph, dma_channel);
	
	uart_dma_config_t* config = uart_dma->config;
    dma_single_data_parameter_struct dma_init_struct;
	while(config->dma_buf_size < 2){

	}
    /* configure the DMA0 channel1 */
    dma_deinit(dma_periph, dma_channel);
    dma_init_struct.direction = DMA_PERIPH_TO_MEMORY;
    dma_init_struct.memory0_addr = (uint32_t)config->dma_buf;
    dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
    dma_init_struct.periph_memory_width = DMA_MEMORY_WIDTH_8BIT;
    dma_init_struct.number = config->dma_buf_size/2;
    dma_init_struct.periph_addr = uart_dma->rx_data_address;
    dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
    dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
    dma_single_data_mode_init(dma_periph, dma_channel, &dma_init_struct);
    dma_channel_subperipheral_select(dma_periph, dma_channel, uart_dma->subperi);
	
	dma_switch_buffer_mode_config(dma_periph, dma_channel, 
		(uint32_t)((uint32_t)config->dma_buf+config->dma_buf_size/2), DMA_MEMORY_0);
	dma_switch_buffer_mode_enable(dma_periph, dma_channel);
//	    dma_circulation_disable(DMA0, DMA_CH1);
    /* enable DMA0 channel1 */
    dma_channel_enable(dma_periph, dma_channel);
	
//	    dma_circulation_enable(dma_periph, dma_channel);
	uint32_t source = DMA_INT_FTF|DMA_INT_FEE;
 	dma_interrupt_enable(dma_periph, dma_channel, source);

    dma_channel_enable(dma_periph, dma_channel);
	
    nvic_irq_enable(uart_dma->rx_irqn, 13, 0);
}

#if 0
static void uart_dma_receive_config(const uart_dma_t* uart_dma)
{
	uint32_t dma_periph = uart_dma->dma_periph;
	dma_channel_enum dma_channel = uart_dma->rx_channel;
    dma_parameter_struct dma_init_struct;
    /* clear all the interrupt flags */
    dma_flag_clear(dma_periph, dma_channel, DMA_FLAG_G);
    dma_flag_clear(dma_periph, dma_channel, DMA_FLAG_FTF);
    dma_flag_clear(dma_periph, dma_channel, DMA_FLAG_HTF);
    dma_flag_clear(dma_periph, dma_channel, DMA_FLAG_ERR);
    dma_channel_disable(dma_periph, dma_channel);
    dma_deinit(dma_periph, dma_channel);
    
    /* configure the DMA1 channel3 */
    dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
    dma_init_struct.memory_addr = (uint32_t)uart_dma->config->dma_buf;
    dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
    dma_init_struct.number = uart_dma->config->dma_buf_size;
    dma_init_struct.periph_addr = uart_dma->data_address;
    dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
    dma_init_struct.priority = DMA_PRIORITY_MEDIUM;
    dma_init(dma_periph, dma_channel, dma_init_struct);
    dma_memory_to_memory_disable(dma_periph, dma_channel);
	
    dma_circulation_enable(dma_periph, dma_channel);
	uint32_t source = DMA_INT_FTF|DMA_INT_ERR|DMA_INT_HTF;
 	dma_interrupt_enable(dma_periph, dma_channel, source);

    dma_channel_enable(dma_periph, dma_channel);
	
    nvic_irq_enable(uart_dma->rx_irqn, 13, 1);
}
#endif 

void BSP_Uart_DMA_Init(void){
    rcu_periph_clock_enable(RCU_DMA0);
    rcu_periph_clock_enable(RCU_DMA1);
}

void BSP_Uart_DMA_ReceiveInit(uint8_t id, uint8_t* dma_buf, uint32_t size, void (*dma_rx_cb)(uint8_t* data, uint32_t size)){
	REQUIRE(id < 4);
	uint32_t uart = uarts[id].entity;
	const uart_dma_t* uart_dma = &uart_dmas[id];
	
	usart_interrupt_disable(uart, USART_INT_RBNE);
	usart_interrupt_disable(uart, USART_INT_IDLE);
	
	uart_dma->config->dma_buf = dma_buf;
	uart_dma->config->dma_buf_size = size;
	uart_dma->config->dma_countor = 0;
	uart_dma->config->dma_rx_cb = dma_rx_cb;
	uart_dma_receive_config(uart_dma);
	
	usart_dma_receive_config(uart, USART_RECEIVE_DMA_ENABLE);
	/* Enable IRQ IDLE to define the end of a
	 * RX DMA transaction.
	 */
	usart_flag_clear(uart, USART_FLAG_IDLE);

	usart_interrupt_enable(uart, USART_INT_IDLE);
}

void BSP_Uart_DMA_Send(uint8_t id, void* buf, uint32_t size, uint8_t flag, void(*tx_cb)(uint8_t flag)){
	REQUIRE(id < 4);
	uint32_t uart = uarts[id].entity;
	const uart_dma_t* uart_dma = &uart_dmas[id];
	uart_dma->config->dma_tx_cb = tx_cb;
	uart_dma->config->dma_tx_flag = flag;
	uart_dma_transfer_config(uart_dma, buf, size);
    usart_dma_transmit_config(uart, USART_TRANSMIT_DMA_ENABLE);
}

int BSP_Uart_DMA_IsSendComplete(uint8_t id){
	REQUIRE(id < 4);
	const uart_dma_t* uart_dma = &uart_dmas[id];
	return dma_flag_get(uart_dma->dma_periph, uart_dma->tx_channel, DMA_FLAG_FTF);
}

static void BSP_Uart_DMA_Flush(const uart_dma_t* uart_dma, uint8_t status){
	uint32_t rx_len;
	uart_dma_config_t* config = uart_dma->config;
	uint8_t* buf = config->dma_buf;
	uint32_t buf_size = uart_dma->config->dma_buf_size / 2;
	
	if(!buf || buf_size == 0){
		return ;
	}
	
	switch(status){
	case 1:{
		//FTF
		//dma使用的上一个缓冲
		uint8_t* last_buf;
		if(dma_using_memory_get(uart_dma->dma_periph, uart_dma->rx_channel) == DMA_MEMORY_1){
			last_buf = buf;
		}
		else{
			last_buf = buf + buf_size;
		}
		rx_len = buf_size - config->dma_countor;
		if(rx_len > 0){
			config->dma_rx_cb(last_buf+config->dma_countor, rx_len);
		}
		config->dma_countor = 0;
	}
	break;
	case 2:{
		//IDLE
		//dma当前使用的缓冲
		uint8_t* cur_buf;
		if(dma_using_memory_get(uart_dma->dma_periph, uart_dma->rx_channel) == DMA_MEMORY_1){
			cur_buf = buf + buf_size;
		}
		else{
			cur_buf = buf;
		}
		uint32_t number = dma_transfer_number_get(uart_dma->dma_periph, uart_dma->rx_channel);
		uint32_t rx_count = buf_size - number;
		rx_len = rx_count - config->dma_countor;
		if(rx_len > 0){
			config->dma_rx_cb(cur_buf+config->dma_countor, rx_len);
		}
		config->dma_countor = rx_count;
	}
	break;
	default :{

	}
	break;
	}	
}


//USART0_RX
void DMA1_Channel5_IRQHandler(void){
	const uint8_t id = 0;
	const uart_dma_t* uart_dma = &uart_dmas[id];
 
	if(RESET != dma_interrupt_flag_get(uart_dma->dma_periph, uart_dma->rx_channel, DMA_INT_FLAG_FTF)){
		dma_interrupt_flag_clear(uart_dma->dma_periph, uart_dma->rx_channel, DMA_INT_FLAG_FTF);
		BSP_Uart_DMA_Flush(uart_dma, 1);
	}
}

//USART0_TX
 void DMA1_Channel7_IRQHandler(void){
 	const uint8_t id = 0;
 	const uart_dma_t* uart_dma = &uart_dmas[id];
 	if(RESET != dma_interrupt_flag_get(uart_dma->dma_periph, uart_dma->tx_channel, DMA_INT_FLAG_FTF)){
 		dma_interrupt_flag_clear(uart_dma->dma_periph, uart_dma->tx_channel, DMA_INT_FLAG_FTF);
 		uint8_t flag = uart_dma->config->dma_tx_flag;
 		uart_dma->config->dma_tx_cb(flag);
 	}
 }

//USART1_RX
void DMA0_Channel5_IRQHandler(void){
	const uint8_t id = 1;
	const uart_dma_t* uart_dma = &uart_dmas[id];
	// if(RESET != dma_interrupt_flag_get(uart_dma->dma_periph, uart_dma->rx_channel, DMA_INT_FLAG_HTF)){
	// 	dma_interrupt_flag_clear(uart_dma->dma_periph, uart_dma->rx_channel, DMA_INT_FLAG_HTF);
	// 	BSP_Uart_DMA_Flush(uart_dma, 0);
	// }
	if(RESET != dma_interrupt_flag_get(uart_dma->dma_periph, uart_dma->rx_channel, DMA_INT_FLAG_FTF)){
		dma_interrupt_flag_clear(uart_dma->dma_periph, uart_dma->rx_channel, DMA_INT_FLAG_FTF);
		BSP_Uart_DMA_Flush(uart_dma, 1);
	}
}
//USART1_TX
 void DMA0_Channel6_IRQHandler(void){
 	const uint8_t id = 1;
 	const uart_dma_t* uart_dma = &uart_dmas[id];
 	if(RESET != dma_interrupt_flag_get(uart_dma->dma_periph, uart_dma->tx_channel, DMA_INT_FLAG_FTF)){
 		dma_interrupt_flag_clear(uart_dma->dma_periph, uart_dma->tx_channel, DMA_INT_FLAG_FTF);
 		uint8_t flag = uart_dma->config->dma_tx_flag;
 		uart_dma->config->dma_tx_cb(flag);
 	}
 }

//USART2_RX
void DMA0_Channel1_IRQHandler(void){
	const uint8_t id = 2;
	const uart_dma_t* uart_dma = &uart_dmas[id];
	// if(RESET != dma_interrupt_flag_get(uart_dma->dma_periph, uart_dma->rx_channel, DMA_INT_FLAG_HTF)){
	// 	dma_interrupt_flag_clear(uart_dma->dma_periph, uart_dma->rx_channel, DMA_INT_FLAG_HTF);
	// 	BSP_Uart_DMA_Flush(uart_dma, 0);
	// }
	if(RESET != dma_interrupt_flag_get(uart_dma->dma_periph, uart_dma->rx_channel, DMA_INT_FLAG_FTF)){
		dma_interrupt_flag_clear(uart_dma->dma_periph, uart_dma->rx_channel, DMA_INT_FLAG_FTF);
		BSP_Uart_DMA_Flush(uart_dma, 1);
	}
}
//UART2_TX
 void DMA0_Channel3_IRQHandler(void){
 	const uint8_t id = 2;
 	const uart_dma_t* uart_dma = &uart_dmas[id];
 	if(RESET != dma_interrupt_flag_get(uart_dma->dma_periph, uart_dma->tx_channel, DMA_INT_FLAG_FTF)){
 		dma_interrupt_flag_clear(uart_dma->dma_periph, uart_dma->tx_channel, DMA_INT_FLAG_FTF);
 		uint8_t flag = uart_dma->config->dma_tx_flag;
 		uart_dma->config->dma_tx_cb(flag);
 	}
 }

static void BSP_Uart_IrqHandler(Uart_T* uart){
    if(RESET != usart_interrupt_flag_get(uart->entity, USART_INT_FLAG_RBNE)){
        /* read one byte from the receive data register */
        uint16_t rx = usart_data_receive(uart->entity);
		uart->cb(rx);
    }
}

void USART0_IRQHandler(void)
{
	uint8_t id = 0;
	Uart_T* uart = &uarts[id];
	BSP_Uart_IrqHandler(uart);
	if(RESET != usart_interrupt_flag_get(uart->entity, USART_INT_FLAG_IDLE)){
		usart_interrupt_flag_clear(uart->entity, USART_INT_FLAG_IDLE);
		usart_data_receive(uart->entity);
		BSP_Uart_DMA_Flush(&uart_dmas[id], 2);
	}
	if(RESET != usart_flag_get(uart->entity, USART_FLAG_ORERR)){
		usart_interrupt_flag_clear(uart->entity, USART_INT_FLAG_ERR_ORERR);
		usart_data_receive(uart->entity);
	}
}

void USART1_IRQHandler(void)
{
	uint8_t id = 1;
	Uart_T* uart = &uarts[id];
	BSP_Uart_IrqHandler(uart);
	if(RESET != usart_interrupt_flag_get(uart->entity, USART_INT_FLAG_IDLE)){
		usart_interrupt_flag_clear(uart->entity, USART_INT_FLAG_IDLE);
		usart_data_receive(uart->entity);
		BSP_Uart_DMA_Flush(&uart_dmas[id], 2);
	}
	if(RESET != usart_flag_get(uart->entity, USART_FLAG_ORERR)){
		usart_interrupt_flag_clear(uart->entity, USART_INT_FLAG_ERR_ORERR);
		usart_data_receive(uart->entity);
	}
}

void USART2_IRQHandler(void)
{
	uint8_t id = 2;
	Uart_T* uart = &uarts[id];
	BSP_Uart_IrqHandler(uart);
	if(RESET != usart_interrupt_flag_get(uart->entity, USART_INT_FLAG_IDLE)){
		usart_interrupt_flag_clear(uart->entity, USART_INT_FLAG_IDLE);
		usart_data_receive(uart->entity);
		BSP_Uart_DMA_Flush(&uart_dmas[id], 2);
	}
	if(RESET != usart_flag_get(uart->entity, USART_FLAG_ORERR)){
		usart_interrupt_flag_clear(uart->entity, USART_INT_FLAG_ERR_ORERR);
		usart_data_receive(uart->entity);
	}
}

